#ifndef	SUDOKU_DEFINITION_H
#define	SUDOKU_DEFINITION_H

#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <unordered_set>
#include <boost/foreach.hpp>

#include "sudoku_group.h"

using namespace std;

class Group;
class GroupUnique;
class SudokuBoard;

//Założenia:
// - indexy pol = 1..n
// - liczba pol = n
//------------------------------------------------------------------------------------------------------------
class SudokuDefinition
{
	public:
        //SudokuDefinition();
        //virtual vector<Group*> getGroups() = 0;
        //virtual void printGroups();
        //virtual void printGroups() = 0;
        int getSize() {return size;};
        vector<int>* getPossibleIndices() {return &possibleIndices;};
		vector<int>* getGeneralPossibleValues() {return &generalPossibleValues;};
		//vector<int> possibleIndices();
		vector<Group*>* getGroups();
		void getGroupsForFieldIdx(map<int,vector<Group*>*>); //groups by fields) {return &groupsForFieldIdx;};
		void getGroupsByField(map<int,vector<Group*>*>* groupsByField);
		void getAvailableSet(int, set<int>*, map<int,int>*); //available set of values for some field (idx)
		void getOrderedMapAvailables(map<int,int>*, map<int,set<int>*>*); //posortowana kolekcja fieldow względem liczby dostępnych wartości
		static void setIntersection(const set<int>*, const set<int>*, set<int>*);
	protected:
        int size;
        vector<Group*> groups;
        //map<int,set<int>*> possibleValuesForFields; //for outside the class
        vector<int> generalPossibleValues; //set of possible values of fields
        int emptyValue;
        vector<int> possibleIndices; //vector of indices of fields
        void buildRelations();
};
//------------------------------------------------------------------------------------------------------------
class SudokuFromFile : public SudokuDefinition
{
    public:
        SudokuFromFile(const char* fileName);
    private:
        int fetchSudokuRel(const char* fileName); //fetch relations from file
};
//------------------------------------------------------------------------------------------------------------
class StandardSudoku : public SudokuDefinition
{
    public:
        StandardSudoku();
        //vector< vector<int>* > getGroups() {return groups;};
        vector<Group*> getGroups() {return groups;};
        void printGroups();
    private:
        void generateGroups();
};
//------------------------------------------------------------------------------------------------------------
#endif
